package face;

import java.lang.ref.Reference;
import java.util.concurrent.locks.ReentrantLock;

import sun.misc.Unsafe;

/**
 * Created by zhangyanfei on 2019/6/6.
 * compare and set
 *
 * CAS
 *
 * @author zhangyanfei
 * @date 2019/06/06
 */
public class CasDemo {

    private static final Unsafe unsafe = Unsafe.getUnsafe();

    private static final long stateOffset;

    private volatile int state;

    static {
        try {
            stateOffset = unsafe.objectFieldOffset
                (CasDemo.class.getDeclaredField("state"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    public void test() throws InterruptedException {
        ReentrantLock reentrantLock = new ReentrantLock(true);
        reentrantLock.lock();
        reentrantLock.lockInterruptibly();
    }

    /**
     * @param expect
     * @param update
     * @return
     */
    protected final boolean compareAndSetState(int expect, int update) {
        //  obj offset expect update    CAS源语 直接操作内存
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

    /**
     * 自旋 保证一定成功
     *
     * @param var1
     * @param var2
     * @param var4
     * @return
     */
    public final int getAndSetInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile();
        } while (!unsafe.compareAndSwapInt(var1, var2, var5, var4));

        return var5;
    }

    public int getIntVolatile() {
        return unsafe.getIntVolatile(state, stateOffset);
    }

}
